<template>
  <div class="editor-input-border">
    <template v-if="isDisabled">
      <Editor
        :id="editId"
        v-model.trim="_value"
        style="height: 300px; overflow-y: hidden"
        :mode="editorModel"
        @onCreated="editorDesignCreated"
      />
    </template>
    <template v-else>
      <Toolbar class="editor-input-border" :editor="editorInstance" :defaultConfig="toolbarConfig" :mode="editorModel" />
      <Editor
        :id="editId"
        style="height: 300px; overflow-y: hidden"
        v-model.trim="_value"
        :mode="editorModel"
        :default-config="contentDefaultConfig"
        @onChange="editorChange"
        @onCreated="editorCreated"
      />
    </template>
  </div>
</template>

<script setup>
import { computed, getCurrentInstance, onUnmounted, ref, useAttrs } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import "@wangeditor/editor/dist/css/style.css";

const { proxy } = getCurrentInstance();
const $attrs = useAttrs();
const props = defineProps({
  isDisabled: {
    type: Boolean,
    default: false
  },
  modelValue: {
    type: String,
    default: ""
  },
  placeholder: {
    type: String,
    default: "请输入内容"
  },
  editId: {
    type: String,
    default: "editor"
  }
});
const emit = defineEmits(["update:modelValue"]);

const _value = computed({
  get() {
    return props.modelValue;
  },
  set(val) {
    emit("update:modelValue", val);
  }
});

const editorInstance = ref(null);
const editorDesignInstance = ref(null);
const toolbarConfig = ref({
  excludeKeys: [
    "insertImage",
    "insertVideo",
    "uploadVideo",
    "uploadImage",
    "group-image",
    "group-video",
    "editVideoSize",
    "|",
    "codeBlock",
    "fullScreen",
    "divider",
    "emotion", // 表情
    "insertLink", // 插入链接
    "todo"
  ]
});

const editorModel = ref("default");
const contentDefaultConfig = ref({
  customPaste: (editor, event) => {
    return;
  }
});

/**
 * 监听粘贴事件
 * @desc 获取复制的文本，并添加下划线
 */
const handlePaste = async event => {
  event.preventDefault();
  let pastedData = event.clipboardData.getData("text");
  if (!pastedData) return;
  if (pastedData.startsWith("editorCopy-")) {
    pastedData = pastedData.replace("editorCopy-", "");
    const underlinedText = pastedData.replace(/\S+/g, "<u>\${" + pastedData + "}</u>");
    return editorInstance.value.dangerouslyInsertHtml(underlinedText);
  }
  editorInstance.value.dangerouslyInsertHtml(pastedData);
};

const editorCreated = editor => {
  editorInstance.value = Object.seal(editor);
  $attrs.disabled && disableEditor();
  document.getElementById(props.editId)?.addEventListener("paste", handlePaste);
};
const getText = str => {
  return str
    .replace(/<[^<p>]+>/g, "")
    .replace(/<[</p>$]+>/g, "")
    .replace(/&nbsp;/gi, "")
    .replace(/<[^<br/>]+>/g, "");
};
const editorChange = () => {
  const val = editorInstance.value.getHtml();
  const text = getText(val);
  emit("update:modelValue", !text ? "" : val);
};
const disableEditor = () => {
  editorInstance.value.disable();
};
const editorDesignCreated = editor => {
  editorDesignInstance.value = Object.seal(editor);
  disableDesignEditor();
};
const disableDesignEditor = () => {
  editorDesignInstance.value.disable();
};

onUnmounted(() => {
  const editor = editorInstance.value;
  document.getElementById(props.editId)?.removeEventListener("paste", handlePaste);
  if (!editor) return;
  editor.destroy();
});
</script>

<style lang="scss">
.editor-input-border {
  border: 1px solid #ccc;
}
</style>
